#include "facecompose.h"
#include "facemask.h"

ComposeFace::ComposeFace (std::string id) {
    name = id;
}
ComposeFace::~ComposeFace () {}

void ComposeFace::Run (const ComposeFaceArgs &input,ComposeFaceArgs& output) {
    Mat             out;
    std::cout << "InputSize: (" << input.srcImage.rows << "," << input.srcImage.cols << ")"<< std::endl;

    assert (input.srcImage.rows == 192 && input.srcImage.cols == 192);
    Mat mask (192, 192, CV_32FC1, face_mask);
    warpAffine (input.srcImage, out, input.transport, Size (input.dstImage.rows, input.dstImage.cols), cv::INTER_LINEAR,
        cv::BORDER_CONSTANT, cv::Scalar (0, 0, 0));
    Mat alphaMask;
    warpAffine (mask, alphaMask, input.transport, Size (input.dstImage.rows, input.dstImage.cols), cv::INTER_LINEAR,
        cv::BORDER_CONSTANT, cv::Scalar (0));

    output.dstImage = input.dstImage;

    for (int y = 0; y < output.dstImage.rows; y++) {
        const float *alpha = alphaMask.ptr<float> (y);
        const uchar *src = out.ptr<uchar> (y);
        uchar       *dst = output.dstImage.ptr<uchar> (y);
        for (int x = 0; x < output.dstImage.cols; x++) {
            if (alpha[x] != 0.0f) {
                dst[x * 3 + 0] = (alpha[x] * src[x * 3 + 0] + (1.0f - alpha[x]) * dst[x * 3 + 0]);
                dst[x * 3 + 1] = (alpha[x] * src[x * 3 + 1] + (1.0f - alpha[x]) * dst[x * 3 + 1]);
                dst[x * 3 + 2] = (alpha[x] * src[x * 3 + 2] + (1.0f - alpha[x]) * dst[x * 3 + 2]);
            }
        }
    }
}
